package com.example.edu.tips;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.regex.Pattern;

public abstract class AbstractWordManage {

    public static final char character = 'A';

    /**
     * 单词树结构
     * <p>
     * a->b
     * a->b->c
     * a->b->d
     * a->b->d->e
     */
    protected final Node wordsTree = new Node();

    protected int RESULT_LIMIT = 15;

    private final Pattern compile = Pattern.compile("^[A-Za-z]+$");

    private final Pattern explainPattern = Pattern.compile("(\\w{1,3}\\.)(.*?)(?=\\w{1,3}\\.|$)");

    public AbstractWordManage() {
        loadFile("/dictionary/word01.txt");
        loadFile("/dictionary/word02.txt");
        loadFile("/dictionary/word03.txt");
    }

    public AbstractWordManage(List<String> filepath) {
        if (filepath != null) {
            for (String path : filepath) {
                loadFile(path);
            }
        }
    }

    private void loadFile(String path) {
        try (BufferedReader br = new BufferedReader(new InputStreamReader(getClass().getResourceAsStream(path), StandardCharsets.UTF_8));) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] wordInfo = line.split("#");
                if (!compile.matcher(wordInfo[0]).matches()) {
                    continue;
                }

                wordInfo[0] = wordInfo[0].trim();
                insert(wordsTree, wordInfo[0].trim(), wordInfo.length == 2 ? wordInfo[1] : "");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void insert(Node root, String words, String explain) {
        char[] chars = words.toCharArray();
        for (char aChar : chars) {
            int charIndex = chargeIndex(aChar);
            if (root.slot[charIndex] == null) {
                root.slot[charIndex] = new Node();
            }
            root = root.slot[charIndex];
            root.c = aChar;
            root.prefix++;
        }

        root.explain = explain;
        root.count++;

    }

    protected static void collect(Node node, String pre, List<Node> queue, int resultLimit) {
        if (node == null) {
            return;
        }

        if (node.count > 0) {
            node.word = pre;
            queue.add(node);
            if (queue.size() >= resultLimit) {
                return;
            }
        }

        for (int i = 0; i < node.slot.length; i++) {
            char character = compensateIndex(i);
            if (node.slot[i] != null) {
                collect(node.slot[i], pre + character, queue, resultLimit);
            }
        }
    }

    protected static char compensateIndex(int charIndex) {
        if (charIndex >= 26) {
            charIndex = charIndex + 6;
        }
        return (char) (charIndex + character);
    }

    protected static int chargeIndex(char aChar) {
        int charIndex = aChar - character;
        if (charIndex >= 32) {
            return charIndex - 6;
        }
        return charIndex;
    }

}
